﻿using Prism.Commands;
using Prism.Events;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows;
using System.Windows.Forms;
using Xcj.Mes.Core.Logger;
using Xcj.Mes.WholeLine.DataBase.Entity;
using Xcj.Mes.WholeLine.DataBase.Service;
using Xcj.Mes.WholeLine.Plc.Events;
using Xcj.Mes.WholeLine.Plc.Factory;
using MessageBox = System.Windows.MessageBox;

namespace Xcj.Mes.WholeLine.ZH.HG.Shell.ViewModels.Config
{
    public class ConfigBaseViewModel : BaseViewModel
    {
        private string _deviceType = string.Empty;
        public string DeviceType
        {
            get => _deviceType;
            set
            {
                _deviceType = value;
                RaisePropertyChanged();
            }
        }

        private Dictionary<string, PlcAddressEntity> _dicPlcAddressEntity = new Dictionary<string, PlcAddressEntity>();
        public Dictionary<string, PlcAddressEntity> DicPlcAddressEntity
        {
            get => _dicPlcAddressEntity;
            set
            {
                _dicPlcAddressEntity = value;
                RaisePropertyChanged();
            }
        }

        private ObservableCollection<PlcAddressEntity> _plcAddressEntities = new ObservableCollection<PlcAddressEntity>();
        public ObservableCollection<PlcAddressEntity> PlcAddressEntities
        {
            get => _plcAddressEntities;
            set
            {
                _plcAddressEntities = value;
                RaisePropertyChanged();
            }
        }

        private int _selectedIndex = -1;
        public int SelectedIndex
        {
            get => _selectedIndex;
            set
            {
                _selectedIndex = value;
                RaisePropertyChanged();
            }
        }

        //SelectedItem
        private PlcAddressEntity _selectedItem;
        public PlcAddressEntity SelectedItem
        {
            get => _selectedItem;
            set
            {
                if (_selectedItem != value)
                {
                    _selectedItem = value;
                    RaisePropertyChanged();

                    // 当选中项变化时，将数据加载到表单中
                    LoadSelectedItemToForm();
                }
            }
        }

        public ObservableCollection<string> BitItems { get; } = new ObservableCollection<string>
        {
            "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"
        };

        /// <summary>
        /// 将选中的行数据加载到表单控件中
        /// </summary>
        private void LoadSelectedItemToForm()
        {
            if (_selectedItem == null)
            {
                // 如果没有选中项，可以清空表单或保持原样
                return;
            }

            try
            {
                // 复制属性值（避免引用问题）
                CopyProperties(_selectedItem, plcAddressEntity);

                // 同步ComboBox的选中项
                PlcDataAddressClassSelectedItem = _selectedItem.AddressClass;
                PlcDataCategorySelectedItem = _selectedItem.DataType;
                PlcDataBitSelectedItem = BitItems[_selectedItem.Bit];
                PlcDataModelSelectedItem = _selectedItem.Mode;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载选中项数据失败：{ex.Message}");
            }
        }

        /// <summary>
        /// 复制属性值
        /// </summary>
        private void CopyProperties(PlcAddressEntity source, PlcAddressEntity target)
        {
            if (source == null || target == null) return;

            target.DeviceType = source.DeviceType;
            target.Name = source.Name;
            target.Address = source.Address;
            target.AddressClass = source.AddressClass;
            target.DataType = source.DataType;
            target.DataLength = source.DataLength;
            target.Bit = source.Bit;
            target.Value = source.Value;
            target.Mode = source.Mode;
            target.HasPeriod = source.HasPeriod;
            target.Period = source.Period;
            target.ID = source.ID;
        }

        private PlcAddressEntity _plcAddressEntity = new PlcAddressEntity();
        public PlcAddressEntity plcAddressEntity
        {
            get => _plcAddressEntity;
            set
            {
                _plcAddressEntity = value;
                RaisePropertyChanged();
            }
        }

        private PlcConfigEntity _plcConfigEntity = new PlcConfigEntity();
        public PlcConfigEntity plcConfigEntity
        {
            get => _plcConfigEntity;
            set
            {
                _plcConfigEntity = value;
                RaisePropertyChanged();
            }
        }

        private ObservableCollection<string> _plcDataCategoryCollection;
        public ObservableCollection<string> PlcDataCategoryCollection
        {
            get => _plcDataCategoryCollection;
            set
            {
                _plcDataCategoryCollection = value;
                RaisePropertyChanged();
            }
        }

        private string _plcDataCategorySelectedItem;
        public string PlcDataCategorySelectedItem
        {
            get => _plcDataCategorySelectedItem;
            set
            {
                _plcDataCategorySelectedItem = value;
                RaisePropertyChanged();

                // 如果需要同步到plcAddressEntity.DataType
                if (plcAddressEntity != null)
                {
                    plcAddressEntity.DataType = value;
                }
            }
        }

        private string _plcDataAddressClassSelectedItem;
        public string PlcDataAddressClassSelectedItem
        {
            get => _plcDataAddressClassSelectedItem;
            set
            {
                if (_plcDataAddressClassSelectedItem != value)
                {
                    _plcDataAddressClassSelectedItem = value;
                    RaisePropertyChanged();

                    // 同步到实体对象的AddressClass属性
                    if (plcAddressEntity != null)
                    {
                        plcAddressEntity.AddressClass = value;
                    }
                }
            }
        }


        private string _plcDataModelSelectedItem;
        public string PlcDataModelSelectedItem
        {
            get => _plcDataModelSelectedItem;
            set
            {
                if (_plcDataModelSelectedItem != value)
                {
                    _plcDataModelSelectedItem = value;
                    RaisePropertyChanged();

                    // 同步到实体对象的Mode属性
                    if (plcAddressEntity != null)
                    {
                        plcAddressEntity.Mode = value;
                    }
                }
            }
        }


        private string _plcDataBitSelectedItem;
        public string PlcDataBitSelectedItem
        {
            get => _plcDataBitSelectedItem;
            set
            {
                if (_plcDataBitSelectedItem != value)
                {
                    _plcDataBitSelectedItem = value;
                    RaisePropertyChanged();

                    // 同步到实体对象的Bit属性（需要转换）
                    if (plcAddressEntity != null && int.TryParse(value, out int bitValue))
                    {
                        plcAddressEntity.Bit = bitValue;
                    }
                }
            }
        }

        private SubscriptionToken _subscriptionToken = null;

        public DelegateCommand SaveCommand { get; private set; }
        public DelegateCommand ClearCommand { get; private set; }
        public DelegateCommand SearchCommand { get; private set; }
        public DelegateCommand AddCommand { get; private set; }
        public DelegateCommand EditCommand { get; private set; }
        public DelegateCommand DeleteCommand { get; private set; }
        public DelegateCommand ImportCommand { get; private set; }
        public DelegateCommand ExportCommand { get; private set; }

        public ConfigBaseViewModel(string deviceType)
        {
            PlcDataCategoryCollection = new ObservableCollection<string>
            {
                "bool",
                "byte",
                "int16",
                "uint16",
                "int32",
                "uint32",
                "int64",
                "uint64",
                "float",
                "double",
                "string"
            };
            Init(deviceType);
            
            // 初始化命令，并关联执行方法
            SaveCommand = new DelegateCommand(OnSave);
            ClearCommand = new DelegateCommand(OnClear);
            SearchCommand = new DelegateCommand(OnSearch);
            AddCommand = new DelegateCommand(OnAdd);
            EditCommand = new DelegateCommand(OnEdit);
            DeleteCommand = new DelegateCommand(OnDelete);
            ImportCommand = new DelegateCommand(OnImport);
            ExportCommand = new DelegateCommand(OnExport);
           
            // 订阅事件
            _subscriptionToken = _eventAggregator?.GetEvent<PlcDataEvent>()?.Subscribe(OnPlcData);
        }
        
        private void OnSave()
        {
            using (PlcConfigService service = new PlcConfigService())
            {
                PlcConfigEntity __plcConfigEntity = service?.All()?.Where(o=>o.DeviceType == DeviceType).OrderByDescending(o => o.CreateTime)?.FirstOrDefault();
                if (__plcConfigEntity == null)
                    service.Add(plcConfigEntity);
                else
                {
                    __plcConfigEntity.DeviceType = plcConfigEntity.DeviceType;
                    __plcConfigEntity.PlcBrand = plcConfigEntity.PlcBrand;
                    __plcConfigEntity.PlcModel = plcConfigEntity.PlcModel;
                    __plcConfigEntity.PlcProtocol = plcConfigEntity.PlcProtocol;
                    __plcConfigEntity.PlcIP = plcConfigEntity.PlcIP;
                    __plcConfigEntity.PlcPort = plcConfigEntity.PlcPort;
                    service.Edit(__plcConfigEntity);
                }
            }
            
            PlcFactory.Init();
        }

        /// <summary>
        /// 清空表单数据
        /// </summary>
        private void OnClear()
        {
            // 清空plcAddressEntity的各个属性，但保留设备类型
            plcAddressEntity.Name = string.Empty;
            plcAddressEntity.Address = string.Empty;
            plcAddressEntity.AddressClass = string.Empty;
            plcAddressEntity.DataType = string.Empty;
            plcAddressEntity.DataLength = 0;
            plcAddressEntity.Bit = 0;
            plcAddressEntity.Value = string.Empty;
            plcAddressEntity.Mode = "只读"; // 重置为默认值
            plcAddressEntity.HasPeriod = false;
            plcAddressEntity.Period = 500; // 重置为默认值
            // 清空ComboBox的选中项
            PlcDataAddressClassSelectedItem = null;
            PlcDataCategorySelectedItem = null;
            PlcDataModelSelectedItem = null;
            PlcDataBitSelectedItem = null;
        }

        /// <summary>
        /// 查询
        /// </summary>
        private void OnSearch()
        {
            PlcAddressEntities.Clear();
            using (PlcAddressService service = new PlcAddressService())
            {
                // 基础查询：按设备类型筛选
                var query = service?.All()?.Where(o => o.DeviceType == DeviceType);

                // 添加其他筛选条件（如果用户输入了筛选值）
                if (!string.IsNullOrWhiteSpace(plcAddressEntity.Name))
                {
                    query = query?.Where(o => o.Name.Contains(plcAddressEntity.Name));
                }

                if (!string.IsNullOrWhiteSpace(plcAddressEntity.Address))
                {
                    query = query?.Where(o => o.Address.Contains(plcAddressEntity.Address));
                }

                if (!string.IsNullOrWhiteSpace(plcAddressEntity.AddressClass))
                {
                    query = query?.Where(o => o.AddressClass == plcAddressEntity.AddressClass);
                }

                if (!string.IsNullOrWhiteSpace(plcAddressEntity.DataType))
                {
                    query = query?.Where(o => o.DataType == plcAddressEntity.DataType);
                }

                if (!string.IsNullOrWhiteSpace(plcAddressEntity.Mode))
                {
                    query = query?.Where(o => o.Mode == plcAddressEntity.Mode);
                }

                if (!string.IsNullOrWhiteSpace(PlcDataBitSelectedItem))
                {
                    query = query?.Where(o => o.Bit == BitItems.IndexOf(PlcDataBitSelectedItem));
                }

                // 按地址排序并执行查询
                var plcAddressEntities = query?.OrderBy(o => o.Address)?.ToList();

                if (plcAddressEntities != null)
                {
                    foreach (var entity in plcAddressEntities)
                    {
                        if (DicPlcAddressEntity.ContainsKey(entity.Address))
                            DicPlcAddressEntity.Remove(entity.Address);
                        DicPlcAddressEntity.Add(entity.Address, entity);
                        PlcAddressEntities.Add(DicPlcAddressEntity[entity.Address]);
                    }
                }
            }
        }

        #region 新增、修改、删除
        /// <summary>
        /// 添加
        /// </summary>
        private void OnAdd()
        {
            // 基础验证
            if (!ValidatePlcAddressEntity())
            {
                return;
            }

            try
            {
                using (PlcAddressService service = new PlcAddressService())
                {
                    //检查是否重复，同个DeviceType不能有相同的Address
                    if (service?.All()?.Where(o => o.DeviceType == plcAddressEntity.DeviceType && o.Address == plcAddressEntity.Address)?.Any() == true)
                    {
                        MessageBox.Show("该设备类型下已存在该地址");
                        return;
                    }
                    plcAddressEntity.ID = 0;
                    service.Add(plcAddressEntity);
                }
                PlcFactory.Init();
                MessageBox.Show("新增成功");
                OnSearch();
                OnClear();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"新增失败：{ex.Message}");
            }
        }

        /// <summary>
        /// 验证PLC地址实体数据
        /// </summary>
        /// <returns>验证通过返回true，否则返回false</returns>
        private bool ValidatePlcAddressEntity()
        {
            // 验证设备类型
            if (string.IsNullOrWhiteSpace(plcAddressEntity.DeviceType))
            {
                MessageBox.Show("设备类型不能为空");
                return false;
            }

            // 验证数据名称
            if (string.IsNullOrWhiteSpace(plcAddressEntity.Name))
            {
                MessageBox.Show("数据名称不能为空");
                return false;
            }

            if (plcAddressEntity.Name.Length > 32)
            {
                MessageBox.Show("数据名称长度不能超过32个字符");
                return false;
            }

            // 验证数据地址
            if (string.IsNullOrWhiteSpace(plcAddressEntity.Address))
            {
                MessageBox.Show("数据地址不能为空");
                return false;
            }

            if (plcAddressEntity.Address.Length > 32)
            {
                MessageBox.Show("数据地址长度不能超过32个字符");
                return false;
            }

            // 验证数据分类
            if (string.IsNullOrWhiteSpace(plcAddressEntity.AddressClass))
            {
                MessageBox.Show("数据分类不能为空");
                return false;
            }

            if (plcAddressEntity.AddressClass.Length > 32)
            {
                MessageBox.Show("数据分类长度不能超过32个字符");
                return false;
            }

            // 验证数据长度
            if (plcAddressEntity.DataLength < 0)
            {
                MessageBox.Show("数据长度不能为负数");
                return false;
            }


            // 验证周期
            if (plcAddressEntity.HasPeriod)
            {
                if (plcAddressEntity.Period <= 0)
                {
                    MessageBox.Show("持续读写周期必须大于0");
                    return false;
                }

                if (plcAddressEntity.Period < 10)
                {
                    MessageBox.Show("持续读写周期建议不小于10ms");
                    return false;
                }
            }

            //将PlcDataBitSelectedItem同步到plcAddressEntity.Bit
            if (!string.IsNullOrWhiteSpace(PlcDataBitSelectedItem))
            {
                if (int.TryParse(PlcDataBitSelectedItem, out int bitValue))
                {
                    plcAddressEntity.Bit = bitValue;
                }
                else
                {
                    switch (PlcDataBitSelectedItem)
                    {
                        case "A":
                            plcAddressEntity.Bit = 10;
                            break;
                        case "B":
                            plcAddressEntity.Bit = 11;
                            break;
                        case "C":
                            plcAddressEntity.Bit = 12;
                            break;
                        case "D":
                            plcAddressEntity.Bit = 13;
                            break;
                        case "E":
                            plcAddressEntity.Bit = 14;
                            break;
                        case "F":
                            plcAddressEntity.Bit = 15;
                            break;
                    }
                }
            }


            return true;
        }

        /// <summary>
        /// 修改
        /// </summary>
        private void OnEdit()
        {
            // 验证是否有选中项
            if (SelectedItem == null)
            {
                MessageBox.Show("请先选择要修改的数据");
                return;
            }

            // 基础验证
            if (!ValidatePlcAddressEntity())
            {
                return;
            }

            try
            {
                using (PlcAddressService service = new PlcAddressService())
                {
                    //检查是否重复，同个DeviceType不能有相同的Address
                    if (service?.All()?.Where(o => o.DeviceType == plcAddressEntity.DeviceType && o.Address == plcAddressEntity.Address && o.ID != plcAddressEntity.ID)?.Any() == true)
                    {
                        MessageBox.Show("该设备类型下已存在该地址");
                        return;
                    }
                    // 更新数据
                    service.Edit(plcAddressEntity);
                }

                // 更新列表中的对应项
                var index = PlcAddressEntities.IndexOf(SelectedItem);
                if (index >= 0)
                {
                    PlcAddressEntities[index].DeviceType = plcAddressEntity.DeviceType;
                    PlcAddressEntities[index].Name = plcAddressEntity.Name;
                    PlcAddressEntities[index].Address = plcAddressEntity.Address;
                    PlcAddressEntities[index].AddressClass = plcAddressEntity.AddressClass;
                    PlcAddressEntities[index].DataType = plcAddressEntity.DataType;
                    PlcAddressEntities[index].DataLength = plcAddressEntity.DataLength;
                    PlcAddressEntities[index].Bit = plcAddressEntity.Bit;
                    PlcAddressEntities[index].Value = plcAddressEntity.Value;
                    PlcAddressEntities[index].Mode = plcAddressEntity.Mode;
                    PlcAddressEntities[index].HasPeriod = plcAddressEntity.HasPeriod;
                    PlcAddressEntities[index].Period = plcAddressEntity.Period;
                }

                PlcFactory.Init();
                MessageBox.Show("修改成功");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"修改失败：{ex.Message}");
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        private void OnDelete()
        {
            // 验证是否有选中项
            if (SelectedItem == null)
            {
                MessageBox.Show("请先选择要删除的数据");
                return;
            }

            try
            {
                // 显示确认对话框
                MessageBoxResult result = MessageBox.Show(
                    "您确定要删除此项吗？",
                    "确认",
                    MessageBoxButton.YesNo,
                    MessageBoxImage.Question
                );

                if (result == MessageBoxResult.Yes)
                {
                    using (PlcAddressService service = new PlcAddressService())
                    {
                        // 删除数据
                        service.Del(SelectedItem);
                    }

                    // 从列表中移除
                    PlcAddressEntities.Remove(SelectedItem);

                    // 清空选中项
                    SelectedItem = null;
                    SelectedIndex = -1;

                    PlcFactory.Init();
                    MessageBox.Show("删除成功");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"删除失败：{ex.Message}");
            }
        } 
        #endregion

        #region 导入
        /// <summary>
        /// 导入
        /// </summary>
        private void OnImport()
        {
            try
            {
                var openFileDialog = new Microsoft.Win32.OpenFileDialog
                {
                    Filter = "CSV文件 (*.csv)|*.csv",
                    DefaultExt = ".csv"
                };

                if (openFileDialog.ShowDialog() == true)
                {
                    // 确认导入
                    if (MessageBox.Show("确定要导入CSV文件中的数据吗？", "确认导入",
                                      MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
                    {
                        return;
                    }

                    var importResult = ImportFromCsv(openFileDialog.FileName);

                    // 显示导入结果
                    string message = $"导入完成！\n成功：{importResult.SuccessCount} 条\n跳过：{importResult.SkippedCount} 条\n失败：{importResult.FailedCount} 条";

                    if (importResult.FailedCount > 0)
                    {
                        message += $"\n\n失败详情：\n{string.Join("\n", importResult.ErrorMessages)}";
                    }

                    MessageBox.Show(message, "导入结果", MessageBoxButton.OK,
                                  importResult.FailedCount > 0 ? MessageBoxImage.Warning : MessageBoxImage.Information);

                    // 导入成功后刷新数据
                    if (importResult.SuccessCount > 0)
                    {
                        OnSearch(); // 重新查询刷新列表
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"导入失败：{ex.Message}", "错误",
                              MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        /// <summary>
        /// 从CSV文件导入数据
        /// </summary>
        private ImportResult ImportFromCsv(string filePath)
        {
            var result = new ImportResult();
            var importedEntities = new List<PlcAddressEntity>();

            // 自动检测文件编码
            Encoding encoding = DetectFileEncoding(filePath);

            using (var reader = new StreamReader(filePath, encoding))
            {
                string line;
                int lineNumber = 0;

                // 读取表头（第一行）
                string header = reader.ReadLine();
                lineNumber++;

                while ((line = reader.ReadLine()) != null)
                {
                    lineNumber++;

                    try
                    {
                        if (string.IsNullOrWhiteSpace(line))
                            continue;

                        var entity = ParseCsvLine(line, lineNumber);
                        if (entity != null)
                        {
                            importedEntities.Add(entity);
                        }
                    }
                    catch (Exception ex)
                    {
                        result.ErrorMessages.Add($"第{lineNumber}行解析失败：{ex.Message}");
                        result.FailedCount++;
                    }
                }
            }

            // 批量处理导入的数据
            ProcessImportedEntities(importedEntities, result);

            return result;
        }

        /// <summary>
        /// 检测文件编码
        /// </summary>
        private Encoding DetectFileEncoding(string filePath)
        {
            // 读取文件的前几个字节来检测BOM
            byte[] buffer = new byte[5];
            using (var file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                file.Read(buffer, 0, 5);
            }

            // 检测BOM标记
            if (buffer[0] == 0x2b && buffer[1] == 0x2f && buffer[2] == 0x76) // UTF-7
                return Encoding.UTF7;
            if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf) // UTF-8
                return Encoding.UTF8;
            if (buffer[0] == 0xff && buffer[1] == 0xfe) // UTF-16 (LE)
                return Encoding.Unicode;
            if (buffer[0] == 0xfe && buffer[1] == 0xff) // UTF-16 (BE)
                return Encoding.BigEndianUnicode;
            if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff) // UTF-32
                return Encoding.UTF32;

            // 如果没有BOM，尝试使用GB2312（中文系统常用编码）
            try
            {
                // 尝试用UTF-8读取第一行，如果能正确读取中文字符，则使用UTF-8
                string testLine = File.ReadLines(filePath, Encoding.UTF8).FirstOrDefault();
                if (!string.IsNullOrEmpty(testLine) && testLine.Contains("设备类型"))
                {
                    return Encoding.UTF8;
                }
            }
            catch
            {
                // 忽略异常，继续尝试其他编码
            }

            // 默认使用GB2312（中文系统常用）
            return Encoding.GetEncoding("GB2312");
        }

        /// <summary>
        /// 解析CSV行数据
        /// </summary>
        private PlcAddressEntity ParseCsvLine(string line, int lineNumber)
        {
            var fields = ParseCsvFields(line);

            if (fields.Length < 11) // 根据表头列数调整
            {
                throw new Exception("列数不足");
            }
            if(fields[9] == "1" || fields[9] == "是" || fields[9] == "0" || fields[9] == "否")
            {
                if (fields[9] == "1" || fields[9] == "是")
                    fields[9] = "TRUE";
                else
                    fields[9] = "FALSE";
            }
            switch (fields[4].ToLower().Trim())
            {
                // 布尔类型
                case "bool":
                case "bit":
                case "coil":    // Modbus 线圈
                case "discrete": // Modbus 离散输入
                    fields[4] = "bool";
                    break;

                // 16位有符号整数 (Modbus 标准 INT)
                case "int":
                case "int16":
                    fields[4] = "int16";  // C# short
                    break;

                // 16位无符号整数
                case "uint":
                case "uln16":
                case "uint16":
                case "word":
                case "holding":     // Modbus 保持寄存器
                case "input":       // Modbus 输入寄存器
                    fields[4] = "uint16";  // C# ushort
                    break;

                // 32位有符号整数
                case "dint":
                case "int32":
                case "long":
                    fields[4] = "int32";  // C# int
                    break;

                // 32位无符号整数
                case "udint":
                case "uln32":
                case "uint32":
                case "dword":
                case "doubleword":
                    fields[4] = "uint32";  // C# uint
                    break;

                // 64位双精度浮点数 -> C# double
                case "double":
                case "lreal":      // PLC 长实数
                case "float64":    // 64位浮点数
                case "real64":
                    fields[4] = "double";
                    break;

                // 32位单精度浮点数 -> C# float
                case "float":
                case "real":       // PLC 实数
                case "single":
                case "float32":
                    fields[4] = "float";
                    break;

                // 字符串
                case "string":
                case "ascii":
                case "char":
                    fields[4] = "string";
                    break;
                default:
                    break;
            }
            var entity = new PlcAddressEntity
            {
                DeviceType = fields[0].Trim(),
                Name = fields[1].Trim(),
                Address = fields[2].Trim(),
                AddressClass = fields[3].Trim(),
                DataType = fields[4].Trim(),
                DataLength = int.TryParse(fields[5], out int length) ? length : 0,
                Bit = int.TryParse(fields[6], out int bit) ? bit : 0,
                Value = fields[7].Trim(),
                Mode = fields[8].Trim(),
                HasPeriod = bool.TryParse(fields[9], out bool hasPeriod) && hasPeriod,
                Period = int.TryParse(fields[10], out int period) ? period : 500
            };

            // 数据验证
            if (string.IsNullOrEmpty(entity.Name))
            {
                throw new Exception("数据名称不能为空");
            }

            if (string.IsNullOrEmpty(entity.Address))
            {
                throw new Exception("数据地址不能为空");
            }

            return entity;
        }

        /// <summary>
        /// 解析CSV字段（处理带引号的字段）
        /// </summary>
        private string[] ParseCsvFields(string line)
        {
            var fields = new List<string>();
            var currentField = new StringBuilder();
            bool inQuotes = false;

            for (int i = 0; i < line.Length; i++)
            {
                char c = line[i];

                if (c == '"')
                {
                    if (inQuotes && i + 1 < line.Length && line[i + 1] == '"')
                    {
                        // 转义的双引号
                        currentField.Append('"');
                        i++; // 跳过下一个引号
                    }
                    else
                    {
                        inQuotes = !inQuotes;
                    }
                }
                else if (c == ',' && !inQuotes)
                {
                    fields.Add(currentField.ToString());
                    currentField.Clear();
                }
                else
                {
                    currentField.Append(c);
                }
            }

            fields.Add(currentField.ToString()); // 添加最后一个字段
            return fields.ToArray();
        }

        /// <summary>
        /// 处理导入的实体数据
        /// </summary>
        private void ProcessImportedEntities(List<PlcAddressEntity> importedEntities, ImportResult result)
        {
            using (var service = new PlcAddressService())
            {
                // 获取现有地址列表，用于检查重复
                var existingAddresses = service.All()
                    .Where(o => o.DeviceType == DeviceType)
                    .Select(o => o.Address)
                    .ToHashSet();

                foreach (var entity in importedEntities)
                {
                    try
                    {
                        // 如果地址已存在，则跳过
                        if (existingAddresses.Contains(entity.Address))
                        {
                            result.SkippedCount++;
                            result.ErrorMessages.Add($"地址 '{entity.Address}' 已存在，已跳过");
                            continue;
                        }

                        // 设置设备类型为当前类型（确保一致性）
                        entity.DeviceType = DeviceType;

                        // 添加到数据库
                        service.Add(entity);
                        result.SuccessCount++;

                        // 添加到现有地址集合，避免同一批导入中的重复
                        existingAddresses.Add(entity.Address);
                    }
                    catch (Exception ex)
                    {
                        result.FailedCount++;
                        result.ErrorMessages.Add($"导入地址 '{entity.Address}' 失败：{ex.Message}");
                    }
                }
            }
        }

        /// <summary>
        /// 导入结果类
        /// </summary>
        public class ImportResult
        {
            public int SuccessCount { get; set; }
            public int SkippedCount { get; set; }
            public int FailedCount { get; set; }
            public List<string> ErrorMessages { get; set; } = new List<string>();
        }
        #endregion

        #region 导出
        /// <summary>
        /// 导出数据到CSV文件
        /// </summary>
        private void ExportToCsv(string filePath, IEnumerable<PlcAddressEntity> data)
        {
            using (var writer = new StreamWriter(filePath, false, Encoding.UTF8))
            {
                // 写入表头
                writer.WriteLine("设备类型,数据名称,数据地址,地址分类,数据类型,数据长度,地址Bit位,当前数值,读写模式,是否周期性读写,读写周期(毫秒),备注");

                // 写入数据行
                foreach (var entity in data)
                {
                    var line = $"{EscapeCsvField(entity.DeviceType)}," +
                               $"{EscapeCsvField(entity.Name)}," +
                               $"{EscapeCsvField(entity.Address)}," +
                               $"{EscapeCsvField(entity.AddressClass)}," +
                               $"{EscapeCsvField(entity.DataType)}," +
                               $"{entity.DataLength}," +
                               $"{entity.Bit}," +
                               $"{EscapeCsvField(entity.Value)}," +
                               $"{EscapeCsvField(entity.Mode)}," +
                               $"{(entity.HasPeriod ? "是":"否")}," +
                               $"{entity.Period}," +
                               $"{EscapeCsvField(entity.Remarks)}"; // 备注字段留空

                    writer.WriteLine(line);
                }
            }
        }

        /// <summary>
        /// 转义CSV字段（处理逗号、引号等特殊字符）
        /// </summary>
        private string EscapeCsvField(string field)
        {
            if (string.IsNullOrEmpty(field))
                return string.Empty;

            // 如果字段包含逗号、引号或换行符，需要用引号包围并转义内部引号
            if (field.Contains(",") || field.Contains("\"") || field.Contains("\r") || field.Contains("\n"))
            {
                return $"\"{field.Replace("\"", "\"\"")}\"";
            }

            return field;
        }
        /// <summary>
        /// 导出
        /// </summary>
        private void OnExport()
        {
            try
            {
                if (PlcAddressEntities == null || !PlcAddressEntities.Any())
                {
                    MessageBox.Show("没有数据可以导出", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                    return;
                }

                var saveFileDialog = new Microsoft.Win32.SaveFileDialog
                {
                    Filter = "CSV文件 (*.csv)|*.csv",
                    FileName = $"{DeviceType}_PLC地址配置_{DateTime.Now:yyyyMMddHHmmss}.csv",
                    DefaultExt = ".csv"
                };

                if (saveFileDialog.ShowDialog() == true)
                {
                    ExportToCsv(saveFileDialog.FileName, PlcAddressEntities);
                    MessageBox.Show($"数据已成功导出到：{saveFileDialog.FileName}", "导出成功",
                                  MessageBoxButton.OK, MessageBoxImage.Information);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"导出失败：{ex.Message}", "错误",
                              MessageBoxButton.OK, MessageBoxImage.Error);
            }
        } 
        #endregion

        private void Init(string deviceType)
        {
            DeviceType = deviceType?.Trim();

            if (string.IsNullOrEmpty(DeviceType)) return;

            plcAddressEntity.DeviceType = deviceType;
            plcConfigEntity.DeviceType = deviceType;
            using (var service = new PlcConfigService())
            {
                var existingEntity = service?.All()?.Where(o => o.DeviceType == DeviceType).OrderByDescending(o => o.CreateTime)?.FirstOrDefault();
                if (existingEntity != null)
                {
                    plcConfigEntity = existingEntity;
                }
            }
            OnSearch();
        }

        private void OnPlcData((string DeviceType, string address, string value) args)
        {
            string deviceType = args.DeviceType?.Trim();
            string address = args.address?.Trim();
            string value = args.value?.Trim();

            // 处理接收到的事件
            if ((string.IsNullOrEmpty(deviceType))
                || (string.IsNullOrEmpty(address))
                || (string.IsNullOrEmpty(value))
                || (deviceType != DeviceType))
                return;

            if (!DicPlcAddressEntity.ContainsKey(address))
                return;

            DicPlcAddressEntity[address].Value = value;
        }

        public override sealed void Dispose()
        {
            // 取消订阅
            try { if (_subscriptionToken != null) _eventAggregator.GetEvent<PlcDataEvent>().Unsubscribe(_subscriptionToken); } catch { }
        }
    }
}
